
#include "timer0_driver.h"
#include "gd32f4xx.h"
#include "systick.h"
#include "gd32f4xx.h"
#include "systick.h"
#include "systick.h"
#include "gd32f4xx_timer.h"
#include "gd32f4xx_rcu.h"

/**
 * 电机
 * 
 * 验证互补输出:
 *  `将PB8短接至PA8`,即接正极,电机转得块;
 *   `将PA8短接至PE7`,即接负极,电机转得慢;
 * 
 * 验证中止输入功能:
 *  `PA6`接线到`Vcc`,则电机停止转动
 *      
 */
void timer0_driver_config(void)
{
    // 配置PA6,复用模式,启用timer0_brkin
    rcu_periph_clock_enable(RCU_GPIOA);
    // 使用下拉模式,
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLDOWN, GPIO_PIN_6);
    // 启用AF1功能
    gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_6);

    // PA8 复用模式,启用timer0_oc0
    rcu_periph_clock_enable(RCU_GPIOA);
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8);
    gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_8);

    // pa8与pa7,pb13,pe8,互补,pa8为正极,pa7,pb13,pe8为负极
    // 开启E8的复用模式
    rcu_periph_clock_enable(RCU_GPIOE);
    gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8);
    gpio_af_set(GPIOE, GPIO_AF_1, GPIO_PIN_8);

    //
    rcu_periph_clock_enable(RCU_TIMER0);
    // 4倍频
    rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
    // 重置
    timer_deinit(TIMER0);
    // 结构体
    timer_parameter_struct initpara;
    timer_struct_para_init(&initpara); // 初始化
    // 分频
    initpara.prescaler = 10000; // 16800hz
    // 周期car
    initpara.period = 168; // 10ms
    timer_init(TIMER0, &initpara);

    // 定时器通道设置
    timer_oc_parameter_struct ocpara;
    timer_channel_output_struct_para_init(&ocpara);
    // 配置极性
    ocpara.outputstate = TIMER_CCX_ENABLE;   // 开启p极
    ocpara.outputnstate = TIMER_CCXN_ENABLE; // 开启n极
    // 通道的正极输出
    timer_channel_output_config(TIMER0, TIMER_CH_0, &ocpara);
    // 通道输出模式
    timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0);
    // 设置ccr,
    timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_0, 168 * 0.8f);

    // 开启定时器timer0
    timer_enable(TIMER0);

    //
    // 高级定时器必须打开`中止输入`功能
    //  break 只针对高级定时器TIMER0 & TIMER7，打开互补保护电路
    /* TIMER通道互补保护电路 */
    timer_break_parameter_struct breakpara;
    /* 初始化TIMER break参数结构体 */
    timer_break_struct_para_init(&breakpara);
    /* break输入的极性 HIGH */

    breakpara.breakpolarity = TIMER_BREAK_POLARITY_HIGH; // 只要监听的引脚出现高电平,则立即停止定时器
    /* 输出自动的启用 */
    breakpara.outputautostate = TIMER_OUTAUTO_ENABLE;
    /* break输入的启用*/
    breakpara.breakstate = TIMER_BREAK_ENABLE;
    /* 配置TIMER0 break */
    timer_break_config(TIMER0, &breakpara);
    /* 启用TIMER0 break */
    timer_break_enable(TIMER0);
}

void timer0_driver_test(void)
{
    systick_config();
    timer0_driver_config();
    while (1)
    {
    }
}
